// ...existing code...
package lin

import (
    "errors"
    "fmt"
    "strings"
)

var 类型映射表 = map[string]map[string]string{
    "mysql": {
        "整数":  "INT",
        "长整数": "BIGINT",
        "文本":  "VARCHAR", // 长度由调用方指定
        "长文本": "TEXT",
        "时间":  "DATETIME",
        "小数":  "DECIMAL", // precision,scale 由调用方指定或默认
        "备注":  "TEXT",
    },
    "orcal": {
        "整数":  "NUMBER",
        "长整数": "NUMBER(19)",
        "文本":  "VARCHAR2",
        "长文本": "CLOB",
        "时间":  "DATE",
        "小数":  "FLOAT",
        "备注":  "CLOB",
    },
    "sqlsever": {
        "整数":  "INT",
        "长整数": "BIGINT",
        "文本":  "NVARCHAR",
        "长文本": "NVARCHAR(MAX)",
        "时间":  "DATETIME",
        "小数":  "DECIMAL",
        "备注":  "NVARCHAR(MAX)",
    },
    "sqlite3": {
        "整数":  "INTEGER",
        "长整数": "BIGINT",
        "文本":  "TEXT",
        "长文本": "TEXT",
        "时间":  "TIMESTAMP",
        "小数":  "REAL",
        "备注":  "TEXT",
    },
}

type S数据库_表结构 struct {
    数据库类型 string
    字段表    J键值表 // key: 字段名 value: 列定义（字符串）
    顺序列    L列表  // 存字段名的顺序
    主键列    []string
}

//mysql orcal sqlsever sqlite3
func (类 *S数据库_表结构) C初始化数据类型(类型 string) error {
    if 类型 != "mysql" && 类型 != "orcal" && 类型 != "sqlsever" && 类型 != "sqlite3" {
        return errors.New("类型不支持")
    }
    类.数据库类型 = 类型
    return nil
}

// 清空当前结构
func (类 *S数据库_表结构) C清空() {
    类.字段表.Q清空()
    类.顺序列.Q清空()
    类.主键列 = nil
}

// internal: 添加或更新字段定义（会保持顺序）
func (类 *S数据库_表结构) addOrUpdate字段(字段名, 定义 string) {
    存在 := 类.字段表.P判断键_是否存在(字段名)
    类.字段表.ZW置文本(定义, 字段名) // value, key
    if !存在 {
        类.顺序列.T添加值(字段名)
    }
}

// 整数列，字段长度=0 则不添加长度
func (类 *S数据库_表结构) Z置整数列(字段名 string, 字段长度 int, 可空 bool, 默认值 string) bool {
    映射表, 存在 := 类型映射表[类.数据库类型]
    if !存在 {
        return false
    }
    列类型 := 映射表["整数"]
    if 字段长度 > 0 && 类.数据库类型 == "mysql" {
        列类型 = fmt.Sprintf("%s(%d)", 列类型, 字段长度)
    }
    def := 列类型
    if !可空 {
        def += " NOT NULL"
    }
    if 默认值 != "" {
        def += " DEFAULT " + 默认值
    }
    类.addOrUpdate字段(字段名, def)
    return true
}

func (类 *S数据库_表结构) Z置长整数列(字段名 string, 可空 bool, 默认值 string) bool {
    映射表, 存在 := 类型映射表[类.数据库类型]
    if !存在 {
        return false
    }
    列类型 := 映射表["长整数"]
    def := 列类型
    if !可空 {
        def += " NOT NULL"
    }
    if 默认值 != "" {
        def += " DEFAULT " + 默认值
    }
    类.addOrUpdate字段(字段名, def)
    return true
}

// 文本列，长度默认255（mysql/sqlsever可设），sqlite3 使用 TEXT
func (类 *S数据库_表结构) Z置文本列(字段名 string, 长度 int, 可空 bool, 默认值 string) bool {
    映射表, 存在 := 类型映射表[类.数据库类型]
    if !存在 {
        return false
    }
    base := 映射表["文本"]
    var 列类型 string
    // sqlite3 文本类型为 TEXT，不需要长度
    if 类.数据库类型 == "sqlite3" || base == "TEXT" || base == "CLOB" {
        列类型 = base
    } else {
        l := 255
        if 长度 > 0 {
            l = 长度
        }
        列类型 = fmt.Sprintf("%s(%d)", base, l)
    }
    def := 列类型
    if !可空 {
        def += " NOT NULL"
    }
    if 默认值 != "" {
        def += " DEFAULT '" + strings.ReplaceAll(默认值, "'", "''") + "'"
    }
    类.addOrUpdate字段(字段名, def)
    return true
}

func (类 *S数据库_表结构) Z置长文本列(字段名 string, 可空 bool) bool {
    映射表, 存在 := 类型映射表[类.数据库类型]
    if !存在 {
        return false
    }
    列类型 := 映射表["长文本"]
    def := 列类型
    if !可空 {
        def += " NOT NULL"
    }
    类.addOrUpdate字段(字段名, def)
    return true
}

func (类 *S数据库_表结构) Z置时间列(字段名 string, 可空 bool, 默认字符串 string) bool {
    映射表, 存在 := 类型映射表[类.数据库类型]
    if !存在 {
        return false
    }
    列类型 := 映射表["时间"]
    def := 列类型
    if !可空 {
        def += " NOT NULL"
    }
    if 默认字符串 != "" {
        // 默认字符串 通常是 'CURRENT_TIMESTAMP' 或者 'YYYY-MM-DD ...'
        def += " DEFAULT " + 默认字符串
    }
    类.addOrUpdate字段(字段名, def)
    return true
}

// 小数列，可指定 precision 和 scale，precision<=0 使用默认 10, scale<=0 使用默认 2
func (类 *S数据库_表结构) Z置小数列(字段名 string, precision, scale int, 可空 bool, 默认值 string) bool {
    映射表, 存在 := 类型映射表[类.数据库类型]
    if !存在 {
        return false
    }
    base := 映射表["小数"]
    if base == "" {
        base = "DECIMAL"
    }
    p := 10
    s := 2
    if precision > 0 {
        p = precision
    }
    if scale > 0 {
        s = scale
    }
    列类型 := fmt.Sprintf("%s(%d,%d)", base, p, s)
    def := 列类型
    if !可空 {
        def += " NOT NULL"
    }
    if 默认值 != "" {
        def += " DEFAULT " + 默认值
    }
    类.addOrUpdate字段(字段名, def)
    return true
}

func (类 *S数据库_表结构) Z置备注列(字段名 string, 可空 bool) bool {
    映射表, 存在 := 类型映射表[类.数据库类型]
    if !存在 {
        return false
    }
    列类型 := 映射表["备注"]
    def := 列类型
    if !可空 {
        def += " NOT NULL"
    }
    类.addOrUpdate字段(字段名, def)
    return true
}

// 设置默认值（直接替换已有定义或追加）
func (类 *S数据库_表结构) Z置默认值(字段名, 默认值 string) bool {
    if !类.字段表.P判断键_是否存在(字段名) {
        return false
    }
    def := 类.字段表.QW取文本(字段名) // 假设 QW取文本(key) 返回 value
    // 移除已有 DEFAULT 子句（简单处理）
    parts := strings.SplitN(def, " DEFAULT ", 2)
    base := parts[0]
    newdef := base + " DEFAULT " + 默认值
    // 保留 NOT NULL 等其他部分（这里为简单替换）
    类.字段表.ZW置文本(newdef, 字段名)
    return true
}

// 设置是否可空
func (类 *S数据库_表结构) Z置可空(字段名 string, 可空 bool) bool {
    if !类.字段表.P判断键_是否存在(字段名) {
        return false
    }
    def := 类.字段表.QW取文本(字段名)
    // 移除 NOT NULL / NULL 关键字（简单处理）
    def = strings.ReplaceAll(def, " NOT NULL", "")
    def = strings.ReplaceAll(def, " NULL", "")
    if !可空 {
        def = def + " NOT NULL"
    }
    类.字段表.ZW置文本(def, 字段名)
    return true
}

// 设置主键（支持多个字段组成复合主键）
func (类 *S数据库_表结构) Z置主键(字段名 string) {
    // 避免重复
    for _, v := range 类.主键列 {
        if v == 字段名 {
            return
        }
    }
    类.主键列 = append(类.主键列, 字段名)
}

// 生成 CREATE TABLE SQL（返回完整的建表语句）
func (类 *S数据库_表结构) C生成创建表SQL(表名 string) (string, error) {
    if 类.数据库类型 == "" {
        return "", errors.New("数据库类型未初始化")
    }
    if 类.顺序列.QS取数量() == 0 {
        return "", errors.New("没有列定义")
    }
    var sb strings.Builder
    sb.WriteString("CREATE TABLE ")
    sb.WriteString(表名)
    sb.WriteString(" (\n")
    for i := 0; i < 类.顺序列.QS取数量(); i++ {
        字段名 := 类.顺序列.QW取文本(i)
        def := 类.字段表.QW取文本(字段名)
        sb.WriteString("  ")
        // 不同数据库可能需要不同的标识符，这里使用通用的反引号 for mysql, 对于其它库建议由调用者自行替换
        sb.WriteString(fmt.Sprintf("`%s` %s", 字段名, def))
        if i < 类.顺序列.QS取数量()-1 || len(类.主键列) > 0 {
            sb.WriteString(",")
        }
        sb.WriteString("\n")
    }
    if len(类.主键列) > 0 {
        sb.WriteString("  PRIMARY KEY (")
        for i, k := range 类.主键列 {
            sb.WriteString("`" + k + "`")
            if i < len(类.主键列)-1 {
                sb.WriteString(", ")
            }
        }
        sb.WriteString(")\n")
    }
    sb.WriteString(");")
    return sb.String(), nil
}

// 生成 ALTER TABLE 增加列 的 SQL 列表（用于新增列）
func (类 *S数据库_表结构) C生成新增列AlterSQL(表名 string) ([]string, error) {
    if 类.数据库类型 == "" {
        return nil, errors.New("数据库类型未初始化")
    }
    var sqls []string
    for i := 0; i < 类.顺序列.QS取数量(); i++ {
        字段名 := 类.顺序列.QW取文本(i)
        def := 类.字段表.QW取文本(字段名)
        // 简化：生成 ADD COLUMN 语句，具体的语法可能根据数据库不同需要调整
        sql := fmt.Sprintf("ALTER TABLE %s ADD COLUMN `%s` %s;", 表名, 字段名, def)
        sqls = append(sqls, sql)
    }
    // 如果有主键需要单独处理（通常修改主键更复杂，这里仅在需要时返回注释）
    if len(类.主键列) > 0 {
        // 注意：在很多数据库上，添加主键需要先确保列不包含 NULL 并且表中数据符合主键约束
        sqls = append(sqls, "-- 注意：需要手动处理主键约束的添加/修改，复合主键: "+strings.Join(类.主键列, ","))
    }
    return sqls, nil
}

// 生成 ALTER TABLE 修改列 的 SQL（简单覆盖实现，实际不同数据库语法不同）
func (类 *S数据库_表结构) C生成修改列AlterSQL(表名 string) ([]string, error) {
    if 类.数据库类型 == "" {
        return nil, errors.New("数据库类型未初始化")
    }
    var sqls []string
    for i := 0; i < 类.顺序列.QS取数量(); i++ {
        字段名 := 类.顺序列.QW取文本(i)
        def := 类.字段表.QW取文本(字段名)
        // 使用 MODIFY 或 ALTER COLUMN 语法会因数据库不同而不同，这里以 MySQL 的 MODIFY 为例并提示调用者根据 DB 调整
        sql := fmt.Sprintf("ALTER TABLE %s MODIFY COLUMN `%s` %s;", 表名, 字段名, def)
        sqls = append(sqls, sql)
    }
    return sqls, nil
}